package easier.app.x.view;

import android.text.InputFilter;
import android.text.InputFilter.LengthFilter;
import android.text.InputType;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.method.HideReturnsTransformationMethod;
import android.text.method.PasswordTransformationMethod;
import android.widget.TextView;
import java.lang.Character.UnicodeBlock;
import java.util.Arrays;
import java.util.Objects;

/**
 * 控制Edittext输入
 */
public class EditInputManager {

    private static final String NUMBER = "0123456789";
    private static final String LETTER = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String PLATENO = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
        + "京津冀晋蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁新农台中武北南兰沈济成广海空军使";

    /**
     * 简化操作用
     */
    public interface CharTest {

        /**
         * @param c 输入的字符
         *
         * @return true:符合要求
         */
        boolean test( char c );
    }

    /**
     * @param editText 通用方法,简化设置InputFilter
     * @param test     黑河,输入字符,返回true or false,用于过滤
     */
    public static void setInput( TextView editText, CharTest test ) {

        InputFilter[] filters = editText.getFilters();
        InputFilter[] copy = Arrays.copyOf( filters, filters.length + 1 );
        copy[filters.length] = new InputFilter() {
            @Override
            public CharSequence filter( CharSequence source, int start, int end, Spanned dest, int dstart, int dend ) {

                for ( int i = start; i < end; i++ ) {
                    char c = source.charAt( i );
                    if ( !test.test( c ) ) {
                        return "";
                    }
                }
                return source;
            }
        };
        editText.setFilters( copy );
    }

    public static boolean checkInput( CharSequence source, CharTest charTest ) {

        if ( TextUtils.isEmpty( source ) ) {
            return false;
        }

        for ( int i = 0; i < source.length(); i++ ) {
            char c = source.charAt( i );
            if ( !charTest.test( c ) ) {
                return false;
            }
        }

        return true;
    }

    /**
     * @param editText 限制输入为身份证
     */
    public static void setInputSfz( TextView editText ) {

        setMaxLength( editText, 18 );

        setInput( editText, new CharTest() {
            @Override
            public boolean test( char c ) {

                /* 只能是数字和Xx */
                return NUMBER.indexOf( c ) != -1 || "Xx".indexOf( c ) != -1;
            }
        } );
    }

    /**
     * @param source 检查是否符合身份证校验
     *
     * @return true:符合
     */
    public static boolean checkSfz( CharSequence source ) {

        if ( TextUtils.isEmpty( source ) ) {
            return false;
        }

        /* 1.检查长度 */
        if ( source.length() < 18 ) {
            return false;
        }

        /* 2.检查最后一位数字 */
        if ( !checkSfzLastNumber( source ) ) {
            return false;
        }

        /* 正则匹配 */
        String target = source.toString();

        //六位地区编码 region
        String region = "((1[1-5]|2[1-3]|3[1-7]|4[1-6]|5[0-4]|6[1-5]|8[1-3])\\d{4})";
        //四位年份 year
        String year = "((19|20)\\d{2})";
        //两位月份 month
        String month = "(0[1-9]|1[0-2])";
        //两位日期 date
        String date = "(0[1-9]|[12]\\d|3[01])";
        //末尾四位编号 code
        String code = "(\\d{3}([0-9xX]))";
        String regex = region + year + month + date + code;

        return target.matches( regex );
    }

    /**
     * @return 计算身份证最后一位字符
     */
    public static char calculateSfzLastNumber( CharSequence source ) {

        if ( TextUtils.isEmpty( source ) ) {
            return '\0';
        }

        int[] x = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
        char[] y = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};

        int length = Math.min( source.length(), 17 );

        int sum = 0;
        for ( int i = 0; i < length; i++ ) {

            int n = source.charAt( i ) - 48;
            sum = sum + n * x[i];
        }
        sum = sum % 11;

        return y[sum];
    }

    /**
     * @param source 检查身份证最后一位是否正确
     *
     * @return true:正确
     */
    public static boolean checkSfzLastNumber( CharSequence source ) {

        if ( TextUtils.isEmpty( source ) ) {
            return false;
        }

        if ( source.length() < 18 ) {
            return false;
        }

        char c = calculateSfzLastNumber( source );
        char c1 = source.charAt( source.length() - 1 );
        if ( c1 == 'x' ) {
            c1 = 'X';
        }

        return c == c1;
    }

    /**
     * @param editText 设置输入数字和字母
     */
    public static void setInputNumberAndLetter( TextView editText ) {

        setInput( editText, new CharTest() {
            @Override
            public boolean test( char c ) {

                /* 只能是数字和字母 */
                return NUMBER.indexOf( c ) != -1 || LETTER.indexOf( c ) != -1;
            }
        } );
    }

    /**
     * @param source 检查是否只包含数字和字母
     */
    public static boolean checkNumberAndLetter( CharSequence source ) {

        if ( TextUtils.isEmpty( source ) ) {
            return false;
        }

        for ( int i = 0; i < source.length(); i++ ) {
            char c = source.charAt( i );
            /* 不是字母,不是数字 */
            if ( NUMBER.indexOf( c ) == -1 && LETTER.indexOf( c ) == -1 ) {
                return false;
            }
        }

        return true;
    }

    public static boolean checkLetter( CharSequence source ) {

        if ( TextUtils.isEmpty( source ) ) {
            return false;
        }

        for ( int i = 0; i < source.length(); i++ ) {
            char c = source.charAt( i );
            /* 不是字母 */
            if ( LETTER.indexOf( c ) == -1 ) {
                return false;
            }
        }

        return true;
    }

    /**
     * @param editText 设置输入电话号
     */
    public static void setInputMobile( TextView editText ) {

        editText.setInputType( InputType.TYPE_CLASS_NUMBER );
        setMaxLength( editText, 11 );
    }

    /**
     * @param editText 设置输入手机号
     */
    public static void setInputPhone( TextView editText ) {

        editText.setInputType( InputType.TYPE_CLASS_PHONE );
        setMaxLength( editText, 11 );
    }

    /**
     * @param source 检查是否是手机号码[首位是1,其余是数字,最大11位数字]
     */
    public static boolean checkMobile( CharSequence source ) {

        if ( TextUtils.isEmpty( source ) ) {
            return false;
        }

        /* 11位 */
        if ( source.length() != 11 ) {
            return false;
        }

        /* 首位1 */
        if ( source.charAt( 0 ) != '1' ) {
            return false;
        }

        /* 全是数字 */
        for ( int i = 2; i < source.length(); i++ ) {
            char c = source.charAt( i );
            if ( NUMBER.indexOf( c ) == -1 ) {
                return false;
            }
        }

        return true;
    }

    /**
     * @param editText 设置输入数字
     */
    public static void setInputNumber( TextView editText ) {

        editText.setInputType( InputType.TYPE_CLASS_NUMBER );
    }

    /**
     * @param source 匹配数字
     *
     * @return true:全是数字
     */
    public static boolean checkNumber( CharSequence source ) {

        if ( TextUtils.isEmpty( source ) ) {
            return false;
        }

        /* 全是数字 */
        for ( int i = 0; i < source.length(); i++ ) {
            char c = source.charAt( i );
            if ( NUMBER.indexOf( c ) == -1 ) {
                return false;
            }
        }

        return true;
    }

    /**
     * @param editText 输入密码,暗文
     */
    public static void setInputTextPassword( TextView editText ) {

        editText.setInputType( InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD );
    }

    /**
     * @param editText 输入密码,明文
     */
    public static void setInputVisibleTextPassword( TextView editText ) {

        editText.setInputType( InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD );
    }

    /**
     * @param editText 显示输入
     */
    public static void setPasswordTransformation( TextView editText ) {

        editText.setTransformationMethod( PasswordTransformationMethod.getInstance() );
    }

    /**
     * @param editText 隐藏输入
     */
    public static void setHideTransformation( TextView editText ) {

        editText.setTransformationMethod( HideReturnsTransformationMethod.getInstance() );
    }

    /**
     * @param editText 清除filter
     */
    public static void clearFilters( TextView editText ) {

        editText.setFilters( new InputFilter[0] );
    }

    /**
     * @param editText  设置输入最大数量字数
     * @param maxLength 最大字数
     */
    public static void setMaxLength( TextView editText, int maxLength ) {

        InputFilter[] filters = editText.getFilters();
        for ( int i = 0; i < filters.length; i++ ) {
            InputFilter filter = filters[i];
            if ( filter instanceof LengthFilter ) {
                filters[i] = new LengthFilter( maxLength );
                editText.setFilters( filters );
                return;
            }
        }

        InputFilter[] copy = Arrays.copyOf( filters, filters.length + 1 );
        copy[filters.length] = new LengthFilter( maxLength );
        editText.setFilters( copy );
    }

    /**
     * @param editText 限制输入只能是汉字名字
     */
    public static void setInputChineseName( TextView editText ) {

        setInput( editText, new CharTest() {
            @Override
            public boolean test( char c ) {

                return isChineseName( c );
            }
        } );
    }

    /**
     * @param source 检查是否是中文名字
     *
     * @return true:中文名字
     */
    public static boolean checkChineseName( CharSequence source ) {

        if ( TextUtils.isEmpty( source ) ) {
            return false;
        }

        for ( int i = 0; i < source.length(); i++ ) {
            char c = source.charAt( i );
            if ( !isChineseName( c ) ) {
                return false;
            }
        }
        return true;
    }

    /**
     * @param editText 限制输入只能是汉字,不包含标点
     */
    public static void setInputChinese( TextView editText ) {

        setInput( editText, new CharTest() {
            @Override
            public boolean test( char c ) {

                /* 只能是汉字 */
                return isChinese( c );
            }
        } );
    }

    /**
     * @param source 检查输入的是否是汉字(不包含标点)
     *
     * @return true:全是汉字(不包含标点)
     */
    public static boolean checkChinese( CharSequence source ) {

        if ( TextUtils.isEmpty( source ) ) {
            return false;
        }

        for ( int i = 0; i < source.length(); i++ ) {
            char c = source.charAt( i );
            if ( !isChinese( c ) ) {
                return false;
            }
        }
        return true;
    }

    /**
     * @param c 检查是否是中文字符包含标点
     */
    public static boolean isChineseUnicode( char c ) {

        UnicodeBlock ub = UnicodeBlock.of( c );
        // 4E00-9FBF：CJK 统一表意符号
        return ub == UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
            //F900-FAFF：CJK 兼容象形文字
            || ub == UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
            //3400-4DBF：CJK 统一表意符号扩展 A
            || ub == UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
            //2000-206F：常用标点
            || ub == UnicodeBlock.GENERAL_PUNCTUATION
            //3000-303F：CJK 符号和标点
            || ub == UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
            //FF00-FFEF：半角及全角形式
            || ub == UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS;
    }

    /**
     * @param c 是否是常用标点符号
     *
     * @return true:是否是标点符号
     */
    public static boolean checkFormsSymbolsPunctuation( char c ) {

        UnicodeBlock ub = UnicodeBlock.of( c );
        return //2000-206F：常用标点
            ub == UnicodeBlock.GENERAL_PUNCTUATION
                //3000-303F：CJK 符号和标点
                || ub == UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
                //FF00-FFEF：半角及全角形式
                || ub == UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS;

    }

    /**
     * @param c 检查字符是否是汉字和"·"
     *
     * @return true
     */
    @SuppressWarnings( "BooleanMethodIsAlwaysInverted" )
    public static boolean isChineseName( char c ) {

        if ( c == '·' ) {
            return true;
        }

        return isChinese( c );
    }

    /**
     * @param source 检测该字符串是否是汉字名字
     *
     * @return 是否中文名字
     */
    public static boolean isChineseName( CharSequence source ) {

        for ( int i = 0; i < source.length(); i++ ) {
            char c = source.charAt( i );
            if ( !isChineseName( c ) ) {
                return false;
            }
        }
        return true;
    }

    /**
     * @param c 是否是汉字
     *
     * @return true
     */
    public static boolean isChinese( char c ) {

        UnicodeBlock ub = UnicodeBlock.of( c );
        // 4E00-9FBF：CJK 统一表意符号
        return ub == UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
            //F900-FAFF：CJK 兼容象形文字
            || ub == UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
            //3400-4DBF：CJK 统一表意符号扩展 A
            || ub == UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A;
    }

    /**
     * @param source 是否是汉字字符串
     *
     * @return true
     */
    public static boolean isChinese( CharSequence source ) {

        for ( int i = 0; i < source.length(); i++ ) {
            char c = source.charAt( i );
            if ( !isChinese( c ) ) {
                return false;
            }
        }
        return true;
    }

    /**
     * 验证手机格式
     *
     * @param mobiles 手机号
     *
     * @return 验证
     */
    @Deprecated
    public static boolean isMobileNumber( CharSequence mobiles ) {

        return checkMobile( mobiles );
    }

    public static void setInputPlateNo( TextView editText ) {

        setInput( editText, new CharTest() {
            @Override
            public boolean test( char c ) {

                return PLATENO.indexOf( c ) != -1;
            }
        } );
    }

    public static boolean isPlateNo( CharSequence no ) {

        if ( no == null || no.equals( "" ) ) {
            return false;
        }

        for ( int i = 0; i < no.length(); i++ ) {
            char c = no.charAt( i );
            /* 不是字母,不是数字 */
            if ( PLATENO.indexOf( c ) == -1 ) {
                return false;
            }
        }

        return true;
    }

    /**
     * 验证str是否为正确的车牌号
     *
     * @return true
     */
    public static boolean checkPlateNo( CharSequence no ) {

        if ( no == null || no.equals( "" ) ) {
            return false;
        }

        final String str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        final String[] str1 = {"京", "津", "冀", "晋", "蒙", "辽", "吉", "黑", "沪", "苏",
            "浙", "皖", "闽", "赣", "鲁", "豫", "鄂", "湘", "粤", "桂", "琼", "渝",
            "川", "贵", "云", "藏", "陕", "甘", "青", "宁", "新", "农", "台", "中",
            "武", "WJ", "亥", "戌", "酉", "申", "未", "午", "巳", "辰", "卯", "寅",
            "丑", "子", "葵", "壬", "辛", "庚", "己", "戊", "丁", "丙", "乙", "甲",
            "河北", "山西", "北京", "北", "南", "兰", "沈", "济", "成", "广", "海", "空",
            "军", "京V", "使"};

        if ( no.equals( "新车" ) ) {
            return true;
        }

        if ( no.length() == 7 ) {
            int h = 0;
            for ( int r = 0; r < no.length(); r++ ) {
                if ( str.indexOf( no.charAt( r ) ) != -1 ) {
                    h++;
                }
            }
            if ( h == 7 ) {
                return true;
            }
        }

        if ( no.length() > 1 ) {
            String jq1 = no.subSequence( 0, 1 ).toString();
            String jq2 = no.subSequence( 0, 2 ).toString();
            for ( String s : str1 ) {
                if ( s.equals( jq1 ) ) {
                    if ( no.length() <= 8 ) {
                        return true;
                    }
                }
                if ( s.equals( jq2 ) ) {
                    if ( no.length() <= 8 ) {
                        return true;
                    }
                }
            }
        }

        return false;
    }

    /**
     * @param source 检查是否是字母和数字的组合
     *
     * @return true:是
     */
    @Deprecated
    public static boolean isNumberAndLetter( CharSequence source ) {

        return checkNumberAndLetter( source );
    }

    /**
     * @param editText 设置只能输入汉字数字字母
     * @param extra    可以设置一个额外的校验,如果该参数不为null,那么输入的字符必须也包含在该参数内
     */
    public static void setInputChineseNumberLetter( TextView editText, String extra ) {

        setInput( editText, new CharTest() {
            @Override
            public boolean test( char c ) {

                if ( TextUtils.isEmpty( extra ) ) {
                    /* 是汉字,是数字,是字母 */
                    return isChinese( c ) || NUMBER.indexOf( c ) != -1 || LETTER.indexOf( c ) != -1;
                } else {
                    /* 是汉字,是数字,是字母,是额外选项 */
                    return isChinese( c ) || NUMBER.indexOf( c ) != -1 || LETTER.indexOf( c ) != -1
                        || extra.indexOf( c ) != -1;
                }
            }
        } );
    }

    /**
     * @param source 检查是否是汉字数字字母和配置的额外的字符组
     * @param extra  额外配置的字符组,需要同时满足
     */
    public static boolean checkChineseNumberLetter( CharSequence source, String extra ) {

        if ( TextUtils.isEmpty( source ) ) {
            return false;
        }

        if ( TextUtils.isEmpty( extra ) ) {
            /* 不是汉字,不是数字,不是字母 */
            for ( int i = 0; i < source.length(); i++ ) {
                char c = source.charAt( i );
                if ( !isChinese( c ) && NUMBER.indexOf( c ) == 1 && LETTER.indexOf( c ) == 1 ) {
                    return false;
                }
            }

        } else {
            /* 不是汉字,不是数字,不是字母,不是额外选项 */
            for ( int i = 0; i < source.length(); i++ ) {
                char c = source.charAt( i );
                if ( !isChinese( c ) && NUMBER.indexOf( c ) == 1 && LETTER.indexOf( c ) == 1
                    && extra.indexOf( c ) == 1 ) {
                    return false;
                }
            }
        }

        return true;
    }

    /**
     * @param editText 设置只能输入汉字地址:汉字()（）#
     */
    public static void setInputAddressStyle0( TextView editText ) {

        setInputChineseNumberLetter( editText, "()（）#" );
    }

    /**
     * @param editText 设置只能输入汉字地址:汉字数字-
     */
    public static void setInputAddressStyle1( TextView editText ) {

        setInput( editText, new CharTest() {
            @Override
            public boolean test( char c ) {

                return isChinese( c ) || NUMBER.indexOf( c ) != -1 || "-".indexOf( c ) != -1;
            }
        } );
    }

    /**
     * @param editText 设置只能输入汉字和数字
     */
    public static void setInputChineseNumber( TextView editText ) {

        setInput( editText, new CharTest() {
            @Override
            public boolean test( char c ) {

                return isChinese( c ) || NUMBER.indexOf( c ) != -1;
            }
        } );
    }

    /**
     * @param source 检查是否只是汉字和数字
     */
    public static boolean checkChineseNumber( CharSequence source ) {

        if ( TextUtils.isEmpty( source ) ) {
            return false;
        }

        for ( int i = 0; i < source.length(); i++ ) {
            char c = source.charAt( i );
            /* 不是汉子,不是数字 */
            if ( !isChinese( c ) && NUMBER.indexOf( c ) == -1 ) {
                return false;
            }
        }

        return true;
    }

    public static void setInputNumberDecimal( TextView editText ) {

        editText.setInputType( InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL );
    }

    public static void setInputNumberDecimal( TextView editText, int maxDecimal ) {

        editText.setInputType( InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL );
        InputFilter[] filters = editText.getFilters();
        InputFilter[] copy = Arrays.copyOf( filters, filters.length + 1 );
        copy[filters.length] = new MaxDecimalFilter( maxDecimal );
        editText.setFilters( copy );
    }

    public static void setInputEmailAddress( TextView editText, int length ) {

        EditInputManager.setMaxLength( editText, length );
        editText.setInputType( InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS );
    }

    public static boolean checkEmailAddress( CharSequence source ) {

        if ( TextUtils.isEmpty( source ) ) {
            return false;
        }

        int a = -1;
        int b = -1;

        for ( int i = 0; i < source.length(); i++ ) {
            char c = source.charAt( i );
            if ( c == '@' ) {
                a = i;
            } else if ( c == '.' ) {
                b = i;
            }
        }

        if ( a == -1 || b == -1 ) {
            return false;
        }

        if ( a > b ) {
            return false;
        }

        return a != 0 && b != source.length() - 1;
    }

    public static class MaxDecimalFilter implements InputFilter {

        private final int maxDecimalLength;

        public MaxDecimalFilter( int maxDecimalLength ) {

            this.maxDecimalLength = maxDecimalLength;
        }

        @Override
        public CharSequence filter( CharSequence source, int start, int end, Spanned dest, int dstart, int dend ) {

            if ( Objects.equals( source, "." ) && TextUtils.isEmpty( dest ) ) {
                return "0.";
            }
            /*判断插入的数据是否有小数点*/
            boolean isDecimal = false;
            int index = source.length();
            for ( int i = 0; i < source.length(); i++ ) {
                char c = source.charAt( i );
                if ( c == '.' ) {
                    isDecimal = true;
                    index = i;
                    break;
                }
            }
            /*有小数点,并且小数点后面多于两位*/
            if ( isDecimal && source.length() - 1 - index > 2 ) {
                source = source.subSequence( 0, index + 3 );
            }
            for ( int i = 0; i < dest.length(); i++ ) {
                char c = dest.charAt( i );
                if ( c == '.' ) {
                    if ( dstart <= i ) {
                        return source;
                    }
                    if ( dest.length() < i + 1 + maxDecimalLength ) {
                        return source;
                    } else {
                        return "";
                    }
                }
            }
            return source;
        }
    }

    /**
     * Emoji 位于 "Emoticons" 和 "Miscellaneous Symbols and Pictographs" Unicode 块中。具体来说，大部分常见的 Emoji 位于 "Miscellaneous Symbols and Pictographs" 块中，该块的范围是 U+1F300 到 U+1F5FF。这个块包含了各种符号、图形和 Emoji 表情，是常见 Emoji 的主要所在。
     *
     * @param c 是否是emoji
     *
     * @return true
     */
    public static boolean isEmoji( char c ) {

        UnicodeBlock ub = UnicodeBlock.of( c );
        // 4E00-9FBF：CJK 统一表意符号
        return ub == UnicodeBlock.EMOTICONS
            //F900-FAFF：CJK 兼容象形文字
            || ub == UnicodeBlock.MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS
            || ub == UnicodeBlock.HIGH_SURROGATES
            || ub == UnicodeBlock.LOW_SURROGATES
            || ub == UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES
            || ub == UnicodeBlock.VARIATION_SELECTORS
            || ub == UnicodeBlock.DINGBATS
            ;
    }

    /**
     * @param source 是否是emoji字符串
     *
     * @return true
     */
    public static boolean isEmoji( CharSequence source ) {

        for ( int i = 0; i < source.length(); i++ ) {
            char c = source.charAt( i );
            if ( !isEmoji( c ) ) {
                return false;
            }
        }
        return true;
    }

    /**
     * @param editText 限制输入只能是emoji
     */
    public static void setInputEmoji( TextView editText ) {

        setInput( editText, new CharTest() {
            @Override
            public boolean test( char c ) {

                return isEmoji( c );
            }
        } );
    }

    /**
     * @param source 检查输入的是否是emoji
     *
     * @return true:全是emoji
     */
    public static boolean checkEmoji( CharSequence source ) {

        if ( TextUtils.isEmpty( source ) ) {
            return false;
        }

        for ( int i = 0; i < source.length(); i++ ) {
            char c = source.charAt( i );
            if ( !isEmoji( c ) ) {
                return false;
            }
        }
        return true;
    }

    /**
     * @param editText 限制输入不能是emoji
     */
    public static void setInputNoEmoji( TextView editText ) {

        setInput( editText, new CharTest() {
            @Override
            public boolean test( char c ) {

                return !isEmoji( c );
            }
        } );
    }

    /**
     * @param source 检查输入的是否是emoji
     *
     * @return true:全不是emoji
     */
    public static boolean checkNoEmoji( CharSequence source ) {

        if ( TextUtils.isEmpty( source ) ) {
            return false;
        }

        for ( int i = 0; i < source.length(); i++ ) {
            char c = source.charAt( i );
            if ( isEmoji( c ) ) {
                return false;
            }
        }
        return true;
    }

    /**
     * @param c 是否是常用输入,中文标点符号数学符号
     *
     * @return true
     */
    public static boolean isChineseSymbolsMath( char c ) {

        UnicodeBlock ub = UnicodeBlock.of( c );
        // 4E00-9FBF：CJK 统一表意符号
        return ub == UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
            //F900-FAFF：CJK 兼容象形文字
            || ub == UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
            //3400-4DBF：CJK 统一表意符号扩展 A
            || ub == UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
            //中文标点符号
            || ub == UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
            //中文及全角标点
            || ub == UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
            //基本拉丁文标点
            || ub == UnicodeBlock.BASIC_LATIN
            //常用数学运算符号
            || ub == UnicodeBlock.MATHEMATICAL_OPERATORS
            //数学运算符号
            || ub == UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A
            || ub == UnicodeBlock.MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B
            || ub == UnicodeBlock.SUPPLEMENTAL_MATHEMATICAL_OPERATORS
            ;
    }

    /**
     * @param source 是否是常用输入,中文标点符号数学符号
     *
     * @return true
     */
    public static boolean isChineseSymbolsMath( CharSequence source ) {

        for ( int i = 0; i < source.length(); i++ ) {
            char c = source.charAt( i );
            if ( !isChineseSymbolsMath( c ) ) {
                return false;
            }
        }
        return true;
    }

    /**
     * @param editText 限制输入只能是中文标点符号数学符号
     */
    public static void setInputChineseSymbolsMath( TextView editText ) {

        setInput( editText, new CharTest() {
            @Override
            public boolean test( char c ) {

                return isChineseSymbolsMath( c );
            }
        } );
    }

    /**
     * @param source 检查输入的是否是中文标点符号数学符号
     *
     * @return true:全是中文标点符号数学符号
     */
    public static boolean checkChineseSymbolsMath( CharSequence source ) {

        if ( TextUtils.isEmpty( source ) ) {
            return false;
        }

        for ( int i = 0; i < source.length(); i++ ) {
            char c = source.charAt( i );
            if ( !isChineseSymbolsMath( c ) ) {
                return false;
            }
        }
        return true;
    }
}